<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\User;
use app\common\model\UserWx;
use think\Db;
use think\Exception;
use think\Validate;
use \addons\epay\library\Service;


/**
 * 支付接口
 */
class Pay extends Api
{
    protected $noNeedLogin = [''];
    protected $noNeedRight = ['*'];

    protected $model = null;

    public function __construct()
    {
        parent::__construct();
        $this->model = new \app\common\model\Order;
    }

    const Source_Mini = 1; //来源 微信小程序
    const Source_H5 = 2; //来源 H5

    const Class_WeChat = 1; //微信支付
    const Class_Wallet = 2; //钱包支付

    const Code_Wechat = 'wechat'; //微信支付code
    const Code_Wallet = 'wallet'; //钱包支付code

    /**
     * 来源
     * @var 1:微信  2:H5
     */
    protected $source = [
        self::Source_Mini,
        self::Source_H5,
    ];

    /**
     * 支付方式
     * @var 1:微信  2:钱包（测试用不开放）
     */
    protected $class = [
        self::Class_WeChat,
        self::Class_Wallet,
    ];


    /**
     * 入口
     *
     */
    public function index()
    {
        $order_sn = $this->request->post('order_sn');
        $source = $this->request->post('source');
        $class = $this->request->post('class');

        $param = [
            'order_sn' => $order_sn,
            'source'   => $source,
            'class'    => $class,
        ];
        //校验传递的参数
        $this->check($param);

        $map = [
            'order_sn'  => $order_sn,
            'user_id'   => $this->auth->id,
            'state'     => 1, //订单状态 1 正常
            'pay_state' => 0, //支付状态 0 待支付
            'expiretime'=> null, //未过期订单
        ];
        //查询符合条件的订单
        $orderData = $this->model->where($map)->find();

        if (!$orderData) $this->error('Illegal operation');
        if ($orderData['order_amount'] <= 0) $this->error('Order amount must be greater than 0');

        switch ($class){
            //微信支付
            case self::Class_WeChat:
                $result = $this->wechat($orderData,$source);
                break;
            //钱包支付
            case self::Class_Wallet:
                $result = $this->wallet($orderData);
                break;
            default:
                break;
        }

        //钱包支付成功
        $data = [
            'order_sn'  => $orderData['order_sn'],
        ];
        $this->success('Order payment succeeded！',$data);
    }

    /**
     *
     * 验证请求参数
     * @param $param
     * @return bool
     */
    protected function check($param){
        $rule = [
            'order_sn'   => 'require',
            'source'     => 'require',
            'class'      => 'require',
        ];

        $msg = [
            'order_sn.require'      => 'Order SN cannot be blank',
            'source.require'    => 'Source cannot be empty',
            'class.require'      => 'Payment method cannot be blank',
        ];

        $validate = new Validate($rule, $msg);
        $result = $validate->check($param);
        if (!$result) {
            $this->error($validate->getError());
            return false;
        }

        if (!in_array($param['source'],$this->source)){
            $this->error('Source not defined');
            return false;
        }

        if (!in_array($param['class'],$this->class)){
            $this->error('Payment method not defined');
            return false;
        }
    }

    /**
     * 微信支付
     * @param $orderData
     * @param $source
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function wechat($orderData,$source){
        //支付金额
        $order_amount = $orderData['order_amount'];
        $userWxModel = new UserWx();
        $map = [
            'type'      => 1, //微信小程序
            'user_id'   => $this->auth->id,
        ];
        $userWxData = $userWxModel->where($map)->find();
        if (!$userWxData || !$userWxData['openid']) $this->error("The user's wechat was not found");

        //创建订单信息
        $params = [
            'amount'    =>  $order_amount, //插件统一支付接口会处理 *100
            'orderid'   =>  $orderData['order_sn'], //订单号
            'type'      =>  "wechat",
            'title'     =>  "Pay", //订单标题
            'notifyurl' =>  $this->request->root(true) . '/addons/epay/api/wechatnotify', //回调地址
            'openid'    =>  $userWxData['openid'], //用户的OpenID小程序支付必须
        ];

        //根据来源 选择支付方法
        switch ($source) {
            case self::Source_Mini:
                $params['method'] = "miniapp"; //小程序
                break;
            /*case self::Source_H5:
                break;*/
        }

        //调用插件统一支付接口
        $result =  Service::submitOrder($params);
        $this->success('Request succeeded',$result);
    }

    /**
     * 钱包支付 测试用
     * @param $orderData
     * @return bool
     */
    protected function wallet($orderData){
        //支付金额
        $order_amount = $orderData['order_amount'];
        //判断用户余额是否足够支付订单
        if ($order_amount < $this->auth->money){
            Db::startTrans();
            try {
                //扣除用户余额
                $memo = 'Payment order：' . $orderData['order_sn'];
                User::money(-$order_amount,$this->auth->id,$memo);
                //更新订单状态
                $this->model->save([
                    'pay_state'     => 1, //支付状态 1 = 已支付
                    'payment'       => $order_amount, //已付款金额 实际金额
                    'payment_code'  => self::Code_Wallet, // 支付方式 代码 钱包 用户余额
                    'payment_time'  => time(),  //支付时间
                ],[
                    'order_sn'  => $orderData['order_sn'],
                    'user_id'   => $this->auth->id,
                ]);
                //发送支付通知
                Db::commit();
            }catch (Exception $e){
                Db::rollback();
                $msg = $e->getMessage();
                $this->error($msg);
            }

        }else{
            $this->error('Insufficient user balance');
        }

        return true;
    }
}
